package com.example.demo.demos.web.config;

import com.example.demo.demos.web.handler.MyAccessDeniedHandler;
import com.example.demo.demos.web.handler.MyAuthenticationFailureHandler;
import com.example.demo.demos.web.handler.MyAuthenticationSuccessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * spring security配置类
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyAccessDeniedHandler accessDeniedHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin() //表单登录认证
                .usernameParameter("username")  //需要和 表单的用户名 提交名称 匹配
                .passwordParameter("password") //需要和 表单的密码 提交名称 匹配
                .loginProcessingUrl("/login") //表单 自定义的提交路径 当发现是 /login时 认为是登陆， 必须和表单提交的地址一样，去执行UserDetailsServiceImpl
                .loginPage("/login.html")//自定义登陆页面
                //登陆成功后 必须跳转一个 post请求
//                .successForwardUrl("/toMain") // 自己跳转时候 使用
//                .successForwardUrl("/main.html") //登陆成功重定向的网址（会报错405 请求方式不对）
//                .successHandler(new MyAuthenticationSuccessHandler("http://www.baidu.com")) //操作成功后跳转地址 前后端分离
                .successHandler(new MyAuthenticationSuccessHandler("/main.html")) //操作成功后跳转地址 前后端分离
//                .failureForwardUrl("/toError");  //失败跳转页面
                .failureHandler(new MyAuthenticationFailureHandler("/error.html"));

        http.authorizeRequests()
                //antMatchers  放行用的  登陆配置 静态文件 等
                .antMatchers("/test").permitAll() //测试使用
                .antMatchers("/error.html").permitAll() //error.html  不需要被认证
                .antMatchers("/login.html").permitAll() // login.html 不需要认证
                .antMatchers("/js/**","/css/**","/images/**").permitAll() //放行静态文件

                //regexMatchers 正则表达式放行
//                .regexMatchers(".+[.]png").permitAll() //正则表达式 放行
//                .regexMatchers(HttpMethod.GET,".+[.]png").permitAll() //正则表达式 放行 带参数 限制 请求方式

                     //mvcMatchers  配置全局路径时
//                .mvcMatchers("/login.html").servletPath("/joker").permitAll()

//                .antMatchers("/main1.html").hasAuthority("admin")// 单一授权
                .antMatchers("/main1.html").hasAnyAuthority("admin","system") //多个权限

//                .antMatchers("/main1.html").hasRole("normal") // 角色授权
                .antMatchers("/main1.html").hasAnyRole("normal") // 多个角色授权
                //ip地址限制
//                .antMatchers("/main.html").hasIpAddress("127.0.0.1") //限制ip地址权限控制

                .anyRequest().authenticated(); // 任何请求 都需要被认证 必须登陆后才可以访问

        http.csrf().disable(); //关闭 防火墙

        //异常处理
        http.exceptionHandling()
                .accessDeniedHandler(accessDeniedHandler);
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }



}
